package com.link_with_health.controller;

import com.link_with_health.common.CacheMap;
import com.link_with_health.common.Result;
import com.link_with_health.common.TokenMap;
import com.link_with_health.model.AdminLogEntity;
import com.link_with_health.model.AdminUserEntity;
import com.link_with_health.model.Constant;
import com.link_with_health.model.DoctorEntity;
import com.link_with_health.model.UserEntity;
import com.link_with_health.service.DoctorService;
import com.link_with_health.service.SmsService;
import com.link_with_health.service.UserService;
import com.link_with_health.utils.JsonUtil;
import com.link_with_health.utils.RandomCodeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.util.Map;

@Controller
@RequestMapping("/api/unLogin")
public class UnLoginController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private CacheMap cacheMap = CacheMap.getInstance();
    private final String AUTH_TOKEN = "Authorization";
    private TokenMap tokenMap = TokenMap.getInstance();


    @Resource
    UserService userService;

    @Resource
    DoctorService doctorService;

    @Resource
    RandomCodeUtil randomCodeUtil;

    @Resource(name = "thirdPartySmsSender")
    SmsService tcSms;

    /**
     * 用户注册信息提交接口
     * @param json 用户注册信息
     * @param request 请求
     * @return 校验结果
     */
    @RequestMapping("/logon")
    @ResponseBody
    public Result logon(@RequestBody Map<String,Object>json
            , HttpServletRequest request){

        try {
            Map<String,Object> logonForm = (Map<String,Object>) json.get("logonForm");
            UserEntity user = JsonUtil.map2obj(logonForm,UserEntity.class);
            userService.addUser(user);
            logger.info("注册成功 "+user);
            return Result.success("注册成功");

        } catch (Exception e) {
            logger.error("[logon failed]",e);
        }
        return Result.fail("注册失败");
    }

    /**
     * 注册信息唯一性校验接口
     * @param json 校验数据
     * @param request 请求
     * @return 结果
     */
    @RequestMapping("/logon/verifyInfo")
    @ResponseBody
    public Result verifyInfo(@RequestBody Map<String,Object> json
            ,HttpServletRequest request){
        String msg = "手机验证失败";
        try {
            String email = String.valueOf(json.get("email"));
            String username = String.valueOf(json.get("username"));

            if(email != null && userService.getUserByEmail(email) != null)
                return Result.fail(msg + " 邮箱已注册");
            if(email != null && userService.getUserByUsername(username) == null)
                return Result.fail(msg + " 用户名已注册");

            //TODO 保存校验记录，留待提交注册时校验数据是否变动
            //

            return Result.success("信息校验成功");

        } catch (Exception e) {
            logger.error("[login failed]",e);
        }

        return Result.fail(msg);
    }

    /**
     * 注册手机号码唯一性校验接口
     * @param json 手机信息
     * @param request 请求
     * @return 结果
     */
    @RequestMapping("/logon/verifyPhone")
    @ResponseBody
    public Result verifyPhone(@RequestBody Map<String,Object> json
            ,HttpServletRequest request){
        try {
            String phone = String.valueOf(json.get("phone"));
            if(userService.getUserByPhone(phone)==null) {
                String code = String.valueOf(randomCodeUtil.randomNum(6));
                tcSms.send(phone,code);
                cacheMap.put(phone,code);
                return Result.success("手机未注册，注意接收验证短信");
            }
        } catch (Exception e) {
            logger.error("[login failed]",e);
        }

        return Result.fail("手机验证失败");
    }

    /**
     * 手机验证码校验接口
     * @param json 数据
     * @param request 请求
     * @return
     */
    @RequestMapping("/verifySmsCode")
    @ResponseBody
    public Result verifySmsCode(@RequestBody Map<String,Object> json
            ,HttpServletRequest request ){
        try {
            String iCode = String.valueOf(json.get("smsCode"));
            String phone = String.valueOf(json.get("phone"));

            String code = String.valueOf(cacheMap.get(phone));

            if(code != null && code.equals(iCode))
                return Result.success("成功验证");

        } catch (Exception e){
            logger.error("[smsCode verify failed]",e);
        }

        return Result.fail("验证码错误");
    }

    /**
     * 邮箱验证码校验接口
     * @param json 数据
     * @param request 请求Email
     * @return
     */
    @RequestMapping("/verifyEmailCode")
    @ResponseBody
    public Result verifyEmailCode(@RequestBody Map<String,Object> json
            ,HttpServletRequest request ){
        try {
            String iCode = String.valueOf(json.get("emailCode"));
            String email = String.valueOf(json.get("email"));

            String code = String.valueOf(cacheMap.get(email));

            if(code != null && code.equals(iCode))
                return Result.success("成功验证");

        } catch (Exception e){
            logger.error("[EmailCode verify failed]",e);
        }

        return Result.fail("验证码错误");
    }

    /**
     * 发送重设密码的验证码接口
     * @param json 数据
     * @param request 请求
     * @return 结果
     */
    @RequestMapping("/sendResetMsg")
    @ResponseBody
    public Result sendResetMsg(@RequestBody Map<String, Object> json
            , HttpServletRequest request){
        String msg = "验证信息发送失败";
        try {
            String phone = String.valueOf(json.get("phone"));
            String email = String.valueOf(json.get("email"));

            if(userService.getUserByPhone(phone)==null) {
                String code = String.valueOf(randomCodeUtil.randomNum(6));
                tcSms.send(phone, code);
                cacheMap.put(phone, code);

                return Result.success("留意接收验证码");
            }
            msg = msg + "" ;
        } catch(Exception e) {
            logger.error("[reset password failed]");
        }

        return Result.fail(msg);
    }


    /**
     * 重设密码接口
     * @param json 数据
     * @param request 请求
     * @return 结果
     */
    @RequestMapping("/reset")
    @ResponseBody
    public Result reset(@RequestBody Map<String, Object> json
            , HttpServletRequest request){
        String msg = "重置失败";
        try {
            String phone = String.valueOf(json.get("phone"));
            String email = String.valueOf(json.get("email"));
            String password = String.valueOf(json.get("password"));

            if(phone != null && phone.length() > 0) {
                String iCode = String.valueOf(json.get("smsCode"));
                String code = String.valueOf(cacheMap.get(phone));

                if(code == null || !code.equals(iCode))
                    return Result.fail("验证码错误");

                UserEntity user = userService.getUserByPhone(phone);
                user.setPassword(password);
                userService.changeUser(user);

                return Result.success("留意接收验证码");
            } else if(email != null && email.length() > 0) {
                String iCode = String.valueOf(json.get("emailCode"));
                String code = String.valueOf(cacheMap.get(email));

                if (code == null || !code.equals(iCode))
                    return Result.fail("验证码错误");

                UserEntity user = userService.getUserByEmail(email);
                user.setPassword(password);
                userService.changeUser(user);
            }

            return Result.success("重置成功");

        } catch(Exception e) {
            logger.error("[reset password failed]");
        }

        return Result.fail(msg);
    }

    /**
     * 退出
     * @param request  请求
     * @return 处理结果
     */
    @RequestMapping("/logout")
    @ResponseBody
    public Result logout(HttpServletRequest request){

        String token = request.getHeader(AUTH_TOKEN);
        if(tokenMap.get(token) instanceof UserEntity)
            try{
                Long userId = ((UserEntity) tokenMap.get(token))
                        .getUserId();

                UserEntity user = userService
                        .getUserByUserId(userId);

                if(user.getIsDoctor()){
                    DoctorEntity entity = doctorService
                            .getDoctorsByUserId(user.getUserId());
                    entity.setDoctorStatus(5);
                    doctorService.changeDoctor(entity);
                }

                int status = ((UserEntity) tokenMap.get(token)).getUserStatus();
                //设置为上线前的状态 下线
                user.setUserStatus(status);
                userService.changeUser(user);

                logger.info("[INFO] USER_LOGOUT "+user);

                tokenMap.remove(token);

                logger.info("[INFO] USER_LOG + "+user.getUsername());


                return Result.success(user.getUsername()+" logout",null);

            } catch (Exception e){
                logger.error("[logout failed]",e);
            }
        else{
            try {

                AdminUserEntity entity = (AdminUserEntity) tokenMap.get(token);
                tokenMap.remove(token);

                return Result.success(entity.getAdminName()+" logout",null);
            } catch(Exception e){
                logger.error("[logout failed]",e);
            }
        }
        return Result.fail("退出失败");
    }

}
